home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
345_01
/
tlpgtok.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-11
|
14KB
|
613 lines
/* TLPGTOK.C - "The Last Cross-referencer" - Pascal Get Token routines */
/* Last Modified: 02/10/89 */
/*
---------------------------------------------------------------------
Copyright (c) 1987-1989, Eduard Schwan Programs [esp] - All rights reserved
TLC (The Last C-Cross-Referencer) and TLP (same, but for Pascal) are
Cross-Reference Generators crafted and shot into the Public Domain by
Eduard Schwan. The source code and executable program may be freely
distributed as long as the copyright/author notices remain intact, and
it is not used in part or whole as the basis of a commercial product.
Any comments, bug-fixes, or enhancements are welcome.
Also, if you find TLC and it's source code useful, a contribution of
$20 (check/money order) is encouraged! Hopefully we will all see more
source code distributed!
Eduard Schwan, 1112 Oceanic Drive, Encinitas, Calif. 92024
---------------------------------------------------------------------
*/
/*
HEADER: The Last Cross-Referencer;
TITLE: TLC/TLP - The Last Cross-Referencer;
VERSION: 1.01;
DESCRIPTION: "TLC/TLP.
Pascal Get Token routines";
KEYWORDS: Utility, Cross-reference, C, Pascal, Apple, Macintosh, APW, Aztec;
SYSTEM: Macintosh MPW, v3.0;
FILENAME: TLPGTOK.C;
WARNINGS: "Has not yet been ported to MS-DOS.
Shareware, $20 Check/Money Order suggested.";
SEE-ALSO: README.TLC,TLCHELP.DOC,TLPHELP.DOC;
AUTHORS: Eduard Schwan;
COMPILERS: AZTEC C65 v3.2b, APPLEIIGS APW C v1.0, APPLE MACINTOSH MPW C v3.0;
*/
/*------------------------ include files -------------------------*/
#include <stdio.h>
#include <ctype.h>
#include "tlc.h"
/*------------------------- definitions -------------------------*/
#define Eoln 0 /* character constants */
#define Tab '\t'
#define CReturn '\r'
#define Newline '\n'
#define Space ' '
#define Minus '-'
#define Plus '+'
#define Equals '='
#define Single_quote '\''
#define Double_quote '"'
#define Dollar_sign '$'
#define Pound_sign '#'
#define Slash '/'
#define Backslash '\\'
#define Open_paren '('
#define Close_paren ')'
#define Open_brace '{'
#define Close_brace '}'
#define Asterisk '*'
#define Period '.'
#define Underscore '_'
/*--------------------- external declarations --------------------*/
#include "tlc.ext"
/*------------------------ static variables -----------------------*/
static char curr_ch;
static pos_int curr_column;
static int error;
static boolean got_token;
static boolean in_comment;
static boolean pushed_token;
static token_rec_type prev_token;
static int sym_length;
static boolean case_sensitive;
static boolean do_underscores;
static boolean del_quotes;
/*================[ init_scanner ]==================*/
VOID init_scanner(Case_Sensitive, Do_Underscores, Del_Quotes)
boolean Case_Sensitive;
boolean Do_Underscores;
boolean Del_Quotes;
{ /* init_scanner() */
/*
debug(printf("init_scanner:case=%d under=%d delq=%d\n",\
Case_Sensitive,Do_Underscores,Del_Quotes);)
*/
case_sensitive = Case_Sensitive;
do_underscores = Do_Underscores;
del_quotes = Del_Quotes;
curr_column = 0;
error = 0;
in_comment = FALSE;
pushed_token= FALSE;
} /* init_scanner() */
/*=================[ push_token ]===================*/
VOID push_token()
{ /* push_token() */
/*
debug(printf("push_token:\n");)
*/
if (pushed_token)
{
fprintf(stderr,"Error! Token stack overflow..");
exit(1);
}
else
{
prev_token = token;
pushed_token = TRUE;
}
} /* push_token() */
/*================[ init_sym_buff ]=================*/
static VOID init_sym_buff()
{ /* init_sym_buff() */
/*-------- do this if no FILLCHAR ------------
pos_int k;
for (k=0;k<LINE_SIZE;k++) token.tok_string[k]=0;
----------------------------------------------*/
FILLCHAR(token.tok_string, LINE_SIZE, 0);
sym_length = 0;
/*debug(printf("init_sym_buff:\n");)*/
} /* init_sym_buff() */
/*================[ add_sym_buff ]=================*/
static VOID add_sym_buff(curr_ch)
char curr_ch;
{ /* add_sym_buff() */
/*
debug(printf("add_sym_buff:'%c'\n",curr_ch);)
*/
if (sym_length < LINE_SIZE)
{
token.tok_string[sym_length] = curr_ch;
sym_length++;
}
} /* add_sym_buff() */
/*================[ del_sym_buff ]=================*/
static VOID del_sym_buff()
{ /* del_sym_buff() */
/*
debug(printf("del_sym_buff:\n");)
*/
if (sym_length > 0)
{
sym_length--;
token.tok_string[sym_length] = Eoln;
}
} /* del_sym_buff() */
/*================[ in_symbolset ]=================*/
static boolean in_symbolset(ch)
register char ch;
{ /* in_symbolset() */
return(
isalpha(ch) || isdigit(ch) || ch==Underscore
);
} /* in_symbolset() */
/*==============[ do_identifier ]===============*/
static VOID do_identifier()
{ /* do_identifier() */
boolean done;
/*
debug(printf("do_identifier:\n");)
*/
done = FALSE;
while (!error && !done)
{
curr_ch = curr_line[curr_column];
if (!case_sensitive)
curr_ch = tolower(curr_ch);
if (curr_ch == Eoln)
done = TRUE;
else
if (in_symbolset(curr_ch))
{
if (curr_ch!=Underscore || do_underscores)
add_sym_buff(curr_ch);
curr_column++;
}
else
done = TRUE;
} /*while*/
if (!error)
got_token = TRUE;
} /* do_identifier() */
/*================[ in_numberset ]=================*/
static boolean in_numberset(ch, nextch,first_time,base)
register char ch;
register char nextch;
register boolean first_time;
register pos_int base;
{ /* in_numberset() */
/* this doesn't quite handle reals correctly.. 2nd signs goof it up */
/* in exponents, i.e. -256E-5 */
return(
isdigit(ch) ||
ch=='e' || (ch==Period && nextch != Period) ||
(base==B_hex && ch>='a' && ch <= 'f') ||
(first_time && (ch==Minus || ch==Plus))
);
} /* in_numberset() */
/*================[ convert_number ]=================*/
static long convert_number(sptr,base)
char* sptr;
pos_int base;
{ /* convert_number() */
register char ch;
register long result;
boolean done;
/*debug(printf("convert_number:'%s'\n",sptr);)*/
result = 0;
done = FALSE;
while (*sptr && !done)
{
ch = *(sptr++);
if (isdigit(ch))
{ /* shift result & add next digit in */
result = result*base + (ch-'0');
}
else
if (base==B_hex && ch>='a' && ch<='f')
result = result*base + (ch-'a'+10);
else
done = TRUE;
/*debug(printf(" added %c and got %ld\n",ch,result););*/
}
return(result);
} /* convert_number() */
/*================[ do_number ]=================*/
static VOID do_number()
{ /* do_number() */
boolean done,
first_time;
pos_int base;
/*debug(printf("do_number:\n");)*/
done = FALSE;
first_time = TRUE;
if (curr_ch == Dollar_sign)
{
base = B_hex;
}
else
base = B_decimal;
while (!error && !done)
{
curr_ch = tolower(curr_line[curr_column]);
if (curr_ch == Eoln)
done = TRUE;
else
{ /* see if it's a valid digit, if so, add it */
if (in_numberset(curr_ch,curr_line[curr_column],first_time,base))
{
add_sym_buff(curr_line[curr_column]);
curr_column++;
first_time = FALSE;
}
else
{
done = TRUE;
/*
debug(printf(" stopping because %c/%d isnt in number_set\n",curr_ch, curr_ch);)
*/
}
} /* see if it's a valid digit, if so, add it */
} /*while*/
/* all done validating & collecting number, now convert it */
if (!error)
token.tok_value = convert_number(token.tok_string,base);
if (!error)
got_token = TRUE;
} /* do_number() */
/*================[ do_str_literal ]=================*/
static VOID do_str_literal()
{ /* do_str_literal() */
char terminator;
boolean done;
/*
debug(printf("do_str_literal:\n");)
*/
terminator = curr_ch; /* single/double quote */
/* remove leading/trailing quotes */
if (del_quotes)
init_sym_buff();
/* read until trailing quote found */
done = FALSE;
while (!error && !done)
{
curr_ch = curr_line[curr_column];
if (curr_ch == Eoln)
{ /* Hit End of line without finding trailing quote - error */
error = TERR_BAD_STR;
}
else
{
if (curr_ch == terminator)
{ /* is it doubled? */
if (curr_line[curr_column+1] == terminator)
{ /* skip past doubled quote, it'll be added below */
curr_column++;
}
else
done = TRUE; /* found trailing quote - end */
}
}
/* if valid character in string, add it to buffer */
if (!error)
{
if (!(done && del_quotes))
add_sym_buff(curr_ch);
}
curr_column++;
} /*while*/
if (!error)
got_token = TRUE;
} /* do_str_literal() */
/*================[ do_special_syms ]=================*/
static VOID do_special_syms()
{ /* do_special_syms() */
/*
debug(printf("do_special_syms:\n");)
*/
/*
the token type for special symbols is the ASCII code of
that symbol, unless it is a multi-char. symbol, in which
case the results of the following line are changed later
*/
token.tok_type = curr_ch;
/*
now handle each character type
*/
switch (curr_ch)
{
case Open_paren:
if (curr_line[curr_column++]==Asterisk)
{
in_comment = curr_ch; /* just to keep track of which comment type.. */
/*debug(puts("(*-- entering comment");)*/
}
else
{
curr_column--;
got_token = TRUE;
}
break;
case Open_brace:
in_comment = curr_ch; /* just to keep track of which comment type.. */
/*debug(puts("{-- entering comment");)*/
break;
case Dollar_sign:
debug(printf(" got $, check next digit='%c'\n",curr_line[curr_column]);)
if (in_numberset(tolower(curr_line[curr_column]),
curr_line[curr_column+1],
TRUE, B_hex))
{
do_number();
token.tok_type = TOK_NCONST;
}
else
got_token = TRUE;
break;
case Minus: /* TEMPORARY SMARTS.. SOMEDAY THIS SHOULD BE DONE IN PARSER! */
/*
debug(printf(" got MINUS: '%c,%c,%c'\n",\
curr_line[curr_column],curr_line[curr_column+1],curr_line[curr_column+2]);)
*/
if ((curr_line[curr_column] != Eoln) &&
isdigit(curr_line[curr_column]))
{
do_number();
token.tok_type = TOK_NCONST;
}
else
got_token = TRUE;
break;
case Equals:
case Pound_sign:
default:
/*------ allow any characters for now, since there aint no parser yet..
error = TERR_BAD_CHR;
-----------------------------------------------*/ got_token = TRUE;
break;
} /*switch*/
} /* do_special_syms() */
/*=================[ get_token ]===================*/
int get_token()
{ /* get_token() */
if (pushed_token)
{ /* retrieve previous token & exit */
token = prev_token;
pushed_token = FALSE;
debug(printf(" get prev. token\n");)
return(0); /* no error */
}
got_token = FALSE;
error = 0;
token.tok_type = 0;
token.tok_value = 0;
token.tok_string[0] = 0;
do {
/*
skip if still in comment from previous call
*/
if (in_comment != 0)
{
while (in_comment &&
(curr_ch = curr_line[curr_column]) != Eoln)
{
/*
debug(printf("--looking for end comment'%c', at [%d]='%c'\n",\
in_comment, curr_column, curr_ch);)
*/
curr_column++;
switch (in_comment)
{
case Open_paren:
if (curr_ch == Asterisk)
{
curr_ch = curr_line[curr_column];
if (curr_ch == Close_paren)
{
in_comment = FALSE;
curr_column++;
/*debug(puts("--*) exiting comment");)*/
}
}
break;
case Open_brace:
if (curr_ch == Close_brace)
{
/*debug(puts("--} exiting comment");)*/
in_comment = FALSE;
}
break;
default:
break;
} /* switch */
}
if (in_comment) /* then must have hit end of line */
{
error = TERR_EOLN;
token.tok_column = curr_column;
curr_column = 0;
}
} /* if in_comment */
/*
skip leading spaces/tabs or trailing \n or \r
*/
if (!error)
{
while (curr_line[curr_column] == Space ||
curr_line[curr_column] == Tab ||
curr_line[curr_column] == CReturn ||
curr_line[curr_column] == Newline)
{
curr_column++;
}
if (curr_line[curr_column] == Eoln)
{ /* hit end of line */
error = TERR_EOLN;
token.tok_column = curr_column;
curr_column = 0;
}
}
/*
now at 1st character of new token, handle it
*/
if (!error)
{ /* if !error */
curr_ch = curr_line[curr_column++];
token.tok_column = curr_column;
if (!case_sensitive)
curr_ch = tolower(curr_ch);
init_sym_buff();
add_sym_buff(curr_ch);
if (!error)
{
if (isalpha(curr_ch) || curr_ch==Underscore)
{
do_identifier();
token.tok_type = TOK_ID;
}
else
if (isdigit(curr_ch))
{
do_number();
token.tok_type = TOK_NCONST;
}
else
if (curr_ch==Single_quote)
{
do_str_literal();
token.tok_type = TOK_SCONST;
token.tok_value = (unsigned int) token.tok_string[0];
}
else
if (curr_ch==Double_quote)
{
do_str_literal();
token.tok_type = TOK_CCONST; /* the infamous "you'll never see this!" */
}
else
{ /* check for special symbols */
do_special_syms();
}
}
} /* if !error */
} while (!(error || got_token));
/*
printf("get_token:typ=%d col=%d val=%ld str='%s' err=%d\n",
token.tok_type,token.tok_column,token.tok_value,token.tok_string,error);
*/
return (error);
} /* get_token() */